home *** CD-ROM | disk | FTP | other *** search
Modula Implementation | 1993-10-24 | 6.8 KB | 266 lines |
- IMPLEMENTATION MODULE MenuTool;
-
- (*
- Menu Tools.
-
- UK __DATE__ __TIME__
- *)
-
- (*IMP_SWITCHES*)
-
- FROM AES IMPORT Key,SpecialKey,KAlt,KCtrl,KLShift,KRShift,Indirect,
- Disabled,GUserDef,GBox,GString,StringPtr,StringRange,
- Root,Nil,ObjectPtr,ObjectIndex,TreePtr,Global,LastOb;
- FROM ApplMgr IMPORT ApplWrite;
- FROM EvntMgr IMPORT MessageBlock,MnSelected;
- FROM MenuMgr IMPORT MenuBar,MenuTNormal;
- FROM WindMgr IMPORT Desk;
- FROM RcMgr IMPORT RcConstrain,GRect;
- FROM ObjcTool IMPORT ObjectXYWH,Parent,IndirectObject,
- NewObjectCallback,DisposeObjectCallback;
- FROM RsrcTool IMPORT SpecialChar;
- FROM WindTool IMPORT GetWorkXYWH,BeginUpdate,EndUpdate;
- FROM PORTAB IMPORT SIGNEDWORD;
- FROM pSTORAGE IMPORT ALLOCATE,DEALLOCATE;
- FROM SYSTEM IMPORT TSIZE;
- CAST_IMPORT
-
- IMPORT GetObject,SetObject;
-
- PROCEDURE ShowMenu(Menu: TreePtr);
-
- CONST MagicMenu = 124;
-
- VAR Id : SIGNEDWORD;
- Ob : ObjectIndex;
- Work: GRect;
- Rect: GRect;
- OldX: SIGNEDWORD;
-
- BEGIN
- IF GetObject.Extnd(Menu,Root) # MagicMenu THEN
- SetObject.Extnd(Menu,Root,MagicMenu); (* set flag *)
-
- GetWorkXYWH(Desk,Work);
- Ob:= 7; (* start with the first drop down menu *)
-
- REPEAT
- IF GetObject.Type(Menu,Ob) = GBox THEN (* drop down menu? *)
- ObjectXYWH(Menu,Ob,Rect); (* get absolute coordinates *)
- OldX:= Rect.GX; (* store old x position *)
- RcConstrain(Work,Rect); (* constrain drop down menu *)
- IF Rect.GX # OldX THEN (* changed? *)
- SetObject.X(Menu,Ob,GetObject.X(Menu,Ob) + (Rect.GX - OldX) - 1);
- END; (* GEM desktop decreases here by 8 pixels in case of low rez *)
- END;
- INC(Ob);
- UNTIL LastOb IN GetObject.Flags(Menu,Ob);
- END;
-
- Id:= MenuBar(Menu,1);
- END ShowMenu;
-
- PROCEDURE HideMenu(Menu: TreePtr);
-
- VAR Id: SIGNEDWORD;
-
- BEGIN
- Id:= MenuBar(Menu,0);
- END HideMenu;
-
- PROCEDURE MenuKey(Menu: TreePtr; EvKey: Key; EvSpecial: SpecialKey): BOOLEAN;
-
- (* format of a menu entry: " open... ^O" or " open... ^O " *)
-
- VAR ShortCut : ARRAY[0..1] OF CHAR;
- MotherTitle: ObjectPtr;
- ChildTitle : ObjectPtr;
- MotherEntry: ObjectPtr;
- ChildEntry : ObjectPtr;
- Msg : MessageBlock;
- Found : BOOLEAN;
-
- PROCEDURE TestEntry(Index: ObjectPtr): BOOLEAN;
-
- VAR String: StringPtr;
- i : StringRange;
-
- BEGIN
- IF GetObject.Type(Menu,Index) = GString THEN
- String:= GetObject.StringPtr(Menu,Index);
- ELSIF GetObject.Type(Menu,Index) = GUserDef THEN
- IF GetObject.Extnd(Menu,Index) = 16 THEN (* Flying Look *)
- IF Indirect IN Menu^[Index].ObFlags THEN
- String:= Menu^[Index].ObSpec.Extension^.Spec.UserBlock^.UBParm^.Parm; (* wouuuh *)
- ELSE
- String:= Menu^[Index].ObSpec.UserBlock^.UBParm^.Parm;
- END;
- END;
- ELSE
- RETURN FALSE;
- END;
-
- IF String # NIL THEN
- i:= 0;
-
- WHILE String^[i] # 0C DO (* go to the end of the string *)
- INC(i);
- END;
-
- DEC(i); (* there was one INC too much *)
-
- IF String^[i] = " " THEN (* skip over last space if there is any *)
- DEC(i);
- END;
-
- IF (String^[i] = ShortCut[1]) AND (String^[i - 1] = ShortCut[0]) THEN
- RETURN TRUE;
- END;
- END;
- RETURN FALSE;
- END TestEntry;
-
- BEGIN
- ShortCut[1]:= SpecialChar(EvKey);
-
- IF ShortCut[1] # 0C THEN
- IF KAlt IN EvSpecial THEN
- ShortCut[0]:= 7C; (* "0123◆X" *)
- ELSIF KCtrl IN EvSpecial THEN
- ShortCut[0]:= 136C; (* "0123^X" *)
- ELSIF SpecialKey{KLShift,KRShift} * EvSpecial # SpecialKey{} THEN
- ShortCut[0]:= 1C; (* "0123⇧X" *)
- ELSE
- ShortCut[0]:= " "; (* "0123 X" *)
- END;
-
- BeginUpdate;
- EndUpdate; (* for certain reasons *)
-
- MotherTitle:= GetObject.Head(Menu,GetObject.Head(Menu,Root));
- ChildTitle:= GetObject.Head(Menu,MotherTitle);
- MotherEntry:= GetObject.Head(Menu,GetObject.Tail(Menu,Root));
- ChildEntry:= GetObject.Head(Menu,MotherEntry);
-
- Found:= FALSE;
- WHILE NOT Found DO
- IF NOT(Disabled IN GetObject.State(Menu,ChildTitle)) THEN
- WHILE NOT Found AND (ChildEntry # MotherEntry) AND (ChildEntry # Nil) DO
- IF NOT(Disabled IN GetObject.State(Menu,ChildEntry)) THEN
- Found:= TestEntry(ChildEntry);
- END;
-
- IF Found THEN
- WITH Msg DO
- Type := MnSelected;
- Id := Global.ApId;
- Length:= 0;
- Title := ChildTitle;
- Item := ChildEntry;
- END;
- MenuTNormal(Menu,ChildTitle,FALSE);
- ApplWrite(Global.ApId,16,Msg);
- END;
-
- ChildEntry:= GetObject.Next(Menu,ChildEntry);
- END;
- END;
-
- ChildTitle:= GetObject.Next(Menu,ChildTitle);
- MotherEntry:= GetObject.Next(Menu,MotherEntry);
- ChildEntry:= GetObject.Head(Menu,MotherEntry);
-
- IF ChildTitle = MotherTitle THEN
- RETURN FALSE;
- END;
- END;
- RETURN Found;
- ELSE
- RETURN FALSE;
- END;
- END MenuKey;
-
- TYPE CallbackPtr = POINTER TO MenuCallback;
-
- CONST About = 9; (* system dependend? *)
-
- VAR BugAction: MenuCallback;
-
- PROCEDURE NewMenuAction(Menu: TreePtr; Item: ObjectIndex; Call: MenuCallback);
-
- VAR Callback: CallbackPtr;
-
- BEGIN
-
- (* bypass GEM bug *)
-
- IF Item = About THEN
- BugAction:= Call;
- RETURN;
- END;
-
- IF Indirect IN GetObject.Flags(Menu,Item) THEN (* just replace caller *)
- #if not UNIX
- Callback:= CAST(CallbackPtr,Menu^[Item].ObSpec.Extension^.Parm);
- #else
-
- #endif
- Callback^:= Call;
- ELSE
- ALLOCATE(Callback,TSIZE(MenuCallback));
- Callback^:= Call;
- IndirectObject(Menu,Item,Callback);
- END;
- END NewMenuAction;
-
- PROCEDURE MenuAction(Menu: TreePtr; Title: ObjectIndex; Item: ObjectIndex);
-
- VAR Callback: POINTER TO MenuCallback;
-
- BEGIN
-
- (* bypass GEM bug *)
-
- IF Item = About THEN
- BugAction(Menu,Title);
- RETURN;
- END;
-
- #if not UNIX
- Callback:= Menu^[Item].ObSpec.Extension^.Parm;
- #else
-
- #endif
- Callback^(Menu,Title);
- END MenuAction;
-
- (*
- PROCEDURE MenuTitleOf(Menu: TreePtr; MenuItem: ObjectIndex): ObjectIndex;
-
- VAR ParentBox: ObjectPtr;
- FirstBox : ObjectPtr;
- Diff : ObjectPtr;
-
- BEGIN
- ParentBox:= Parent(Menu,MenuItem);
- FirstBox := GetObject.Head(Menu,GetObject.Tail(Menu,Root));
-
- Diff:= 0;
- WHILE FirstBox # ParentBox DO
- INC(Diff);
- FirstBox:= GetObject.Next(Menu,FirstBox);
- END;
-
- RETURN GetObject.Head(Menu,
- GetObject.Head(Menu,
- GetObject.Head(Menu,Root))) + Diff;
- END MenuTitleOf;
- *)
-
- #if not proc_const
- BEGIN
- (*NewMenuAction:= NewObjectCallback;*)
- DisposeMenuAction:= DisposeObjectCallback;
- #endif
- END MenuTool.
-